import copy
import numpy as np



def init_deploy(self,each_ms_kind_deploy_number):
    for ms_kind in self.cloud_system.ms_kind_list:
        for _ in range(each_ms_kind_deploy_number):
            node_list_t=copy.copy(self.cloud_system.bare_metal_node_list)
            while True:
                #如果没有可以部署的服务器，则退出
                if len(node_list_t)==0:
                    print('init_deploy')
                    exit(-1)
                    break
                aim_node=self.cloud_system.random_generator.choice(node_list_t)
                if aim_node.deploy_ms(ms_kind, without_coldstart=True):
                    break
                else:
                    node_list_t.remove(aim_node)
                    
def deploy_greedy(self):
        #统计队列中不同类型的任务分别有哪些，然后减去目前相应微服务空闲的数量，得到需要新部署的微服务的数量
        #微服务随机放到不同的服务器上
        need_ms_kind_list={}
        
        for task in self.cloud_system.pending_task_queue:
            if task.ms_kind in need_ms_kind_list.keys():
                need_ms_kind_list[task.ms_kind]+=1
            else:
                need_ms_kind_list[task.ms_kind]=1
                
        for ms_kind in need_ms_kind_list.keys():
            idle_num=self.cloud_system.get_idle_num_with_ms_kind(ms_kind)
            node_list_t=copy.copy(self.cloud_system.bare_metal_node_list)
            for i in range(max(0, need_ms_kind_list[ms_kind]-idle_num)):
                #如果没有可以部署的服务器，则退出
                if len(node_list_t)==0:
                    break
                np.random.shuffle(node_list_t)
                while True:
                    if len(node_list_t)==0:
                        print("schedule node_list_t wrong")
                        exit(-1)
                    if node_list_t[0].deploy_ms(ms_kind):
                        break
                    else:
                        del node_list_t[0]

        return
    
    


    
    
    
def schedule_greedy(self, replica_num=1):
    for task in self.cloud_system.pending_task_queue:
        task.update_prohibit_ms_id_list()
        self.schedule_to_early_available_ms(task,1)
    #清空队列
    self.cloud_system.pending_task_queue=[]
    
def schedule_to_early_available_ms(self, task, replica_num):
    #获取所有正在运行的微服务列表
    ms_obj_list=self.cloud_system.get_available_ms_obj_with_ms_kind(task.ms_kind)
    #获取每个微服务队列信息，并升序排序
    ##统计每个类型的微服务队列长度信息
    ms_obj_with_early_start_time_list=[]
    for ms_obj in ms_obj_list:
        #如果在禁止的列表中，则跳过
        if ms_obj.ms_id in task.prohibit_ms_id_list:
            continue
        queue_len=ms_obj.get_queue_len()
        TT=0
        if task.parent_task!=None:
            #处理父task有多个副本的情况，传输时间取平均值
            for parent_ms_obj in task.parent_task.aim_ms_obj_list:
                TT+=self.cloud_system.get_TT_time(task.parent_task,parent_ms_obj ,task, ms_obj)
            TT=TT/len(task.parent_task.aim_ms_obj_list)
        early_start_time=TT+queue_len*task.deal_time
        ms_obj_with_early_start_time_list.append([early_start_time, ms_obj])
    if len(ms_obj_with_early_start_time_list)==0:
        return False
        # print("schedule_to_early_available_ms wrong!")
        # exit(-1)
    ms_obj_with_early_start_time_list.sort(key=lambda x:x[0])
    ##调度到微服务上
    for _ in range(replica_num):
        aim_ms=ms_obj_with_early_start_time_list[0][1]
        aim_ms.put_task_to_queue(task)
        ms_obj_with_early_start_time_list[0][0]+=task.deal_time
        ms_obj_with_early_start_time_list.sort(key=lambda x:x[0])
        task.aim_ms_obj_list.append(aim_ms)
    return True